package ord2.impl.webservice;

import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import ord2.core.Parameter;
import ord2.core.Parametric;
import ord2.core.Result;
import ord2.core.StringQuery;
import ord2.search.Searcher;
import ord2.search.SearcherFactory;
import ord2.webservice.WebService;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 * 
 * @author SemiNick
 */
public final class DefaultWebService extends Thread implements WebService, Parametric {
    
    private ServerSocket soc;
    
    public DefaultWebService(Parameter[] pars) {
        
        try {

            int port = 7997;
            for (Parameter p : pars) {

                if (p.getName().equals("port")) {

                    port = Integer.parseInt(p.getValue());
                }
            }
            this.soc = new ServerSocket(port);
        } catch (IOException ex) {

            ex.printStackTrace();
        }
        
    }
    
    @Override
    public void run() {
        
        try {
            
            while (true) {
            
                Socket ss = this.soc.accept();
                ProcessRequest pr = new ProcessRequest();
                pr.s = ss;
                pr.start();
            }
        } catch (Exception e) {
            
            e.printStackTrace();;
        }
    }

    @Override
    public Parameter[] getParameters() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void addParameter(Parameter newParameter) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void removeParameter(Parameter par) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    private static class ProcessRequest extends Thread {
        
        public Socket s = null;
        
        @Override
        public void run() {
            
            try {
                
                InputStream is = this.s.getInputStream();
                DataOutputStream dous = new DataOutputStream(this.s.getOutputStream());
                /*StringBuilder sb = new StringBuilder();
                int b = 0;
                while ((b = is.read()) != -1) {
                    
                    sb.append((char) b);
                }*/
                
                DocumentBuilder fact = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                Document doc = fact.parse(is);
                Node fchild = doc.getFirstChild();
                Node query = fchild.getAttributes().getNamedItem("query");
                
                StringQuery sq = new StringQuery(query.getTextContent());
                @SuppressWarnings("unchecked")
                Searcher<String, File> sss = (Searcher<String, File>) SearcherFactory
                        .getInstance().getAttachedInstance("lucene");
                List<Result<File>> res = sss.query(sq);
                StringBuilder sb = new StringBuilder();
                sb.append("<?xml version=\"1.0\" encoding=\"utf-8\" />");
                if (res != null) {
                    
                    sb.append("<Response status=\"0\" >");
                    for (Result<File> r : res) {
                        
                        File f = r.getValue();
                        sb.append("<Document>");
                        sb.append(f.getAbsolutePath());
                        sb.append("</Document>");
                    }
                    sb.append("</Response>");
                } else {
                    
                    sb.append("<Response status=\"0\" />");
                }
                
                dous.writeUTF(sb.toString());
                dous.flush();
                dous.close();
            } catch (Exception e) {
                
                e.printStackTrace();
            }
        }
    }
}
